﻿using MailKit;
using MailKit.Net.Imap;
using MailKit.Search;
using MimeKit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace EmailHelper.IMAP
{
    /// <summary>
    /// IMAP帮助类
    /// </summary>
    public class ImapHelper
    {
        /// <summary>
        /// 获取所有服务器文件夹
        /// </summary>
        /// <param name="client"></param>
        public static List<IMailFolder> GetFolders(ImapClient client)
        {
            //获取所有文件夹
            List<IMailFolder> mailFolders = client.GetFolders(client.PersonalNamespaces[0]).ToList();
            //var folder = client.GetFolder("INBOX");
            //Console.WriteLine("folder:" + folder.FullName);

            ////获取所有文件夹，同上面
            //var folder2 = client.GetFolder(client.PersonalNamespaces[0]);
            //foreach (var item in folder2.GetSubfolders(false))
            //{
            //    Console.WriteLine("folder2:" + item.FullName);
            //}
            return mailFolders;
        }

        /// <summary>
        /// 获取指定文件名的服务器文件夹
        /// </summary>
        /// <param name="client"></param>
        /// <param name="folderName"></param>
        /// <returns></returns>
        public static IMailFolder GetFolder(ImapClient client, string folderName)
        {
            IMailFolder folder = client.GetFolder(folderName);
            return folder;
        }

        /// <summary>
        /// 从指定文件夹获取邮件头
        /// </summary>
        /// <param name="client"></param>
        /// <param name="folderName"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        public static void GetSummary(ImapClient client, string folderName, DateTime startTime, DateTime endTime)
        {
            var folder = client.GetFolder(folderName); //INBOX
            //打开文件夹并设置为读的方式
            folder.Open(MailKit.FolderAccess.ReadOnly);

            //获取大于2019-9-1时间的所有邮件的唯一Id
            //var uids = folder.Search(SearchQuery.DeliveredAfter(startTime).And(SearchQuery.DeliveredBefore(endTime)));
            var uids = folder.Search(SearchQuery.DeliveredAfter(startTime));

            //获取邮件头
            IList<IMessageSummary> messages = folder.Fetch(uids, MessageSummaryItems.UniqueId | MessageSummaryItems.Full);
            messages.ToList().ForEach((q) => Console.WriteLine(q.UniqueId + q.Envelope.Subject));

            ////获取完整邮件
            //foreach (var item in uids)
            //{
            //    MimeMessage message = folder.GetMessage(new UniqueId(item.Id));
            //    Console.WriteLine(message.HtmlBody);
            //}
        }


        /// <summary>
        /// 从指定文件夹获取邮件头
        /// </summary>
        /// <param name="client"></param>
        /// <param name="folderName"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        public static void GetSummary(ImapClient client, string folderName, HashSet<string> fields, DateTime startTime, DateTime endTime)
        {
            var folder = client.GetFolder(folderName); //INBOX
            //打开文件夹并设置为读的方式
            folder.Open(MailKit.FolderAccess.ReadOnly);

            //获取大于2019-9-1时间的所有邮件的唯一Id
            var uids = folder.Search(SearchQuery.DeliveredAfter(startTime).And(SearchQuery.DeliveredBefore(endTime)));
            //var uids = folder.Search(SearchQuery.DeliveredAfter(startTime));

            //获取邮件头
            IList<IMessageSummary> messages = folder.Fetch(uids, MessageSummaryItems.UniqueId | MessageSummaryItems.Full ,fields);
            messages.ToList().ForEach((q) => Console.WriteLine(q.UniqueId + q.Envelope.Subject));

            ////获取完整邮件
            //foreach (var item in uids)
            //{
            //    MimeMessage message = folder.GetMessage(new UniqueId(item.Id));
            //    Console.WriteLine(message.HtmlBody);
            //}
        }

        /// <summary>
        /// 获取摘要（邮件头）
        /// </summary>
        /// <param name="client"></param>
        public static void GetSummary(ImapClient client, string folderName)
        {
            //var inbox = client.Inbox;
            var folder = client.GetFolder(folderName); //INBOX
            //打开文件夹并设置为读的方式
            folder.Open(FolderAccess.ReadOnly);

            //为两个索引（包括两个索引）之间的消息获取消息摘要
            //MessageSummaryItems items = MessageSummaryItems.UniqueId;
            //MessageSummaryItems items = MessageSummaryItems.Headers;
            //MessageSummaryItems items = MessageSummaryItems.Envelope;
            //MessageSummaryItems items = MessageSummaryItems.UniqueId | MessageSummaryItems.Full;
            MessageSummaryItems items = MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure | MessageSummaryItems.Fast; //mixin中的设置.时间长
            //MessageSummaryItems items = MessageSummaryItems.UniqueId | MessageSummaryItems.Fast;
            foreach (var summary in folder.Fetch(0, -1, items))
            {
                //Console.WriteLine("[summary] {0:D2}: {1}", summary.Index, summary.Envelope.Subject);
                Console.WriteLine("[summary] {0:D2}", summary.Index);
            }
        }

        /// <summary>
        /// 从指定文件夹获取邮件体
        /// </summary>
        /// <param name="client"></param>
        /// <param name="folderName"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        public static void GetBody(ImapClient client, string folderName, DateTime startTime, DateTime endTime)
        {
            var folder = client.GetFolder(folderName); //INBOX
            //打开文件夹并设置为读的方式
            folder.Open(MailKit.FolderAccess.ReadOnly);

            //获取大于2019-9-1时间的所有邮件的唯一Id
            //var uids = folder.Search(SearchQuery.DeliveredAfter(startTime).And(SearchQuery.DeliveredBefore(endTime)));
            var uids = folder.Search(SearchQuery.DeliveredAfter(startTime));
            //获取完整邮件
            foreach (var item in uids)
            {
                MimeMessage message = folder.GetMessage(new UniqueId(item.Id));
                Console.WriteLine(message.HtmlBody);
            }
        }


        /// <summary>
        /// 获取主题
        /// </summary>
        /// <param name="client"></param>
        public static void GetSubject(ImapClient client, IMailFolder serverFolder)
        {
            //获取邮箱文件夹。默认的收件箱文件夹叫INBOX。
            // The Inbox folder is always available on all IMAP servers...  
            //var inbox = client.Inbox;
            serverFolder.Open(FolderAccess.ReadOnly);

            Console.WriteLine("Total messages: {0}", serverFolder.Count);
            Console.WriteLine("Recent messages: {0}", serverFolder.Recent);

            for (int i = 0; i < serverFolder.Count; i++)
            {
                var message = serverFolder.GetMessage(i);
                Console.WriteLine("Subject: {0}", message.Subject);
            }
        }


        /// <summary>
        /// 接收邮件
        /// </summary>
        public static void ImapReceiveEmail(ImapClient client)
        {
            client.Inbox.Open(FolderAccess.ReadOnly);
            var uids = client.Inbox.Search(SearchQuery.All);
            foreach (var uid in uids)
            {
                var message = client.Inbox.GetMessage(uid);
                //message.WriteTo($"{uid}.eml");
            }
            client.Disconnect(true);
        }

        /// <summary>
        /// 下载邮件内容
        /// </summary>
        public static void DownloadBodyParts()
        {
            ImapClient client = new ImapClient();
            //bool res = EmailServerConnect.ConnectServer(client);

            client.Inbox.Open(FolderAccess.ReadOnly);

            // 搜索Subject标题包含“MimeKit”或“MailKit”的邮件
            var query = SearchQuery.SubjectContains("MimeKit").Or(SearchQuery.SubjectContains("MailKit"));
            var uids = client.Inbox.Search(query);

            // 获取搜索结果的摘要信息（我们需要UID和BODYSTRUCTURE每条消息，以便我们可以提取文本正文和附件）
            var items = client.Inbox.Fetch(uids, MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure);

            foreach (var item in items)
            {
                // 确定一个目录来保存内容
                var directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "/MailBody", item.UniqueId.ToString());

                Directory.CreateDirectory(directory);

                // IMessageSummary.TextBody是一个便利的属性，可以为我们找到“文本/纯文本”的正文部分
                var bodyPart = item.TextBody;

                // 下载'text / plain'正文部分
                var body = (TextPart)client.Inbox.GetBodyPart(item.UniqueId, bodyPart);

                // TextPart.Text是一个便利的属性，它解码内容并将结果转换为我们的字符串
                var text = body.Text;

                File.WriteAllText(Path.Combine(directory, "body.txt"), text);

                // 现在遍历所有附件并将其保存到磁盘
                foreach (var attachment in item.Attachments)
                {
                    // 像我们对内容所做的那样下载附件
                    var entity = client.Inbox.GetBodyPart(item.UniqueId, attachment);

                    // 附件可以是message / rfc822部件或常规MIME部件
                    var messagePart = entity as MessagePart;
                    if (messagePart != null)
                    {
                        var rfc822 = messagePart;

                        var path = Path.Combine(directory, attachment.PartSpecifier + ".eml");

                        //rfc822.Message.WriteTo(path);
                    }
                    else
                    {
                        var part = (MimePart)entity;

                        // 注意：这可能是空的，但大多数会指定一个文件名
                        var fileName = part.FileName;

                        var path = Path.Combine(directory, fileName);

                        // decode and save the content to a file
                        //using (var stream = File.Create(path))
                        //part.Content.DecodeTo(stream);
                    }
                }
                client.Disconnect(true);
            }
        }



    }
}
